今天我們要撰寫第一個工具來蒐集所有的 ID
實作部分也很簡單只要遇到 ID
就直接儲存起來即可。
import SwiftSyntax
import SwiftParser
final class IdentifierVisitor: SyntaxVisitor {
lazy var ids: [IdentifierExprSyntax] = []
override final func visit(_ node: IdentifierExprSyntax) -> SyntaxVisitorContinueKind {
ids.append(node)
return .visitChildren
}
}
private func parse(_ code: String) ->[String] {
let ast = Parser.parse(source: code)
let visitor = IdentifierVisitor(viewMode: .sourceAccurate)
visitor.walk(ast)
return visitor.ids.map {
$0.withoutTrivia().description
}
}
然後透過測試來驗證剛剛所蒐集到的 ID
。
import Foundation
import SwiftSyntax
import SwiftParser
import XCTest
final class IDTests: XCTestCase {
func testCode() {
let code = """
import Foundation
let global = Out()
class Out {
func test() {
print(global)
}
}
func test() {
class In {
let a = 1
func test(a: String) {
let inner = In()
print(self.a, a, 123)
func test2() {
escape {
nonescape {
self.test(a: "leak")
print(inner)
}
}
}
}
}
}
func escape(block: @escaping () -> Void) {}
func nonescape(block: () -> Void) {}
"""
let expect = [
// let global = Out()
"Out",
/// print(global)
"print", "global",
/// let inner = In()
"In",
/// print(self.a, a, 123)
"print", "self", "a",
/// escape {
"escape",
/// nonescape {
"nonescape",
/// self.test(a: "leak")
"self",
/// print(inner)
"print", "inner",
]
XCTAssertEqual(parse(code), expect)
}
}
我們從一整段 code,進一步拿到所有 ID
TODO: 消除雜訊